﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace lfm.EndPoints
{
    public class Tag
    {
        /// <summary>
        /// Get the metadata for an Tag on Last.fm
        /// </summary>
        /// <param name="ID">Tag Name</param>
        /// <returns>lfm.Tag</returns>
        public static async Task<lfm.Tag> getInfo(String Tag)
        {
            String s = String.Format("{0}&method=tag.getInfo&tag={1}", Base.APIUrl, Uri.EscapeDataString(Tag));

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Tag.getInfo(await Base.DownloadString(u)); ;
        }

        /// <summary>
        /// Search for tags similar to this one. Returns tags ranked by similarity, based on listening data.
        /// </summary>
        /// <param name="Tag"> The tag name</param>
        /// <returns>List of lfm.Tag</returns>
        public static async Task<List<lfm.Tag>> getSimilar(String Tag)
        {
            String s = String.Format("{0}&method=tag.getSimilar&tag={1}", Base.APIUrl, Uri.EscapeDataString(Tag));

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Generic.getTags(await Base.DownloadString(u)); ;
        }

        /// <summary>
        /// Get the top albums tagged by this tag, ordered by tag count.
        /// </summary>
        /// <param name="Tag">The tag name</param>
        /// <param name="Page">The page number to fetch. Defaults to first page.</param>
        /// <param name="Limit">The number of results to fetch per page. Defaults to 50</param>
        /// <returns>List of lfm.Album</returns>
        public static async Task<List<lfm.Album>> getTopAlbums(String Tag, Int32? Page, Int32? Limit)
        {
            String s = String.Format("{0}&method=tag.getTopAlbums&tag={1}", Base.APIUrl, Uri.EscapeDataString(Tag));
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();
            if (Page.HasValue) s += "&page=" + Page.Value.ToString();

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Artist.getTopAlbums(await Base.DownloadString(u)); ;
        }

        /// <summary>
        /// Get the top artists tagged by this tag, ordered by tag count.
        /// </summary>
        /// <param name="Tag">The tag name</param>
        /// <param name="Page">The page number to fetch. Defaults to first page.</param>
        /// <param name="Limit">The number of results to fetch per page. Defaults to 50</param>
        /// <returns>List of lfm.Artist</returns>
        public static async Task<List<lfm.Artist>> getTopArtists(String Tag, Int32? Page, Int32? Limit)
        {
            String s = String.Format("{0}&method=tag.getTopArtists&tag={1}", Base.APIUrl, Uri.EscapeDataString(Tag));
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();
            if (Page.HasValue) s += "&page=" + Page.Value.ToString();

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Tag.getTopArtists(await Base.DownloadString(u)); ;
        }

        /// <summary>
        /// Fetches the top global tags on Last.fm, sorted by popularity (number of times used)
        /// </summary>
        /// <returns>List of lfm.Tag</returns>
        public static async Task<List<lfm.Tag>> getTopTags()
        {
            String s = String.Format("{0}&method=tag.getTopTags", Base.APIUrl);

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Generic.getTags(await Base.DownloadString(u)); ;
        }

        /// <summary>
        /// Get an artist chart for a tag, for a given date range. If no date range is supplied, it will return the most recent artist chart for this tag.
        /// </summary>
        /// <param name="Tag">The tag name</param>
        /// <param name="Limit">The number of results to fetch per page. Defaults to 50.</param>
        /// <returns>List of lfm.Artist</returns>
        public static async Task<List<lfm.Artist>> getWeeklyArtistChart(String Tag, Int32? Limit)
        {
            String s = String.Format("{0}&method=tag.getweeklyartistchart&tag={1}", Base.APIUrl, Uri.EscapeDataString(Tag));
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Tag.getWeeklyArtistChart(await Base.DownloadString(u)); ;
        }

        /// <summary>
        /// Search for a tag by name. Returns matches sorted by relevance.
        /// </summary>
        /// <param name="Tag">The tag name</param>
        /// <param name="Page">The page number to fetch. Defaults to first page.</param>
        /// <param name="Limit">The number of results to fetch per page. Defaults to 30.</param>
        /// <returns>List of lfm.Tag</returns>
        public static async Task<List<lfm.Tag>> search(String Tag, Int32? Page, Int32? Limit)
        {
            String s = String.Format("{0}&method=tag.search&tag={1}", Base.APIUrl, Uri.EscapeDataString(Tag));
            if (Limit.HasValue) s += "&limit=" + Limit.Value.ToString();
            if (Page.HasValue) s += "&page=" + Page.Value.ToString();

            Uri u = new Uri(s, UriKind.RelativeOrAbsolute);
            return await Parser.Generic.getTags(await Base.DownloadString(u)); ;
        }
    }
}
